package edu.gatech.bsbmule.model;

import java.util.List;
import java.util.Random;


/**
 * This class represents the Land Office, where players can
 * buy and sell land.
 * 
 * @author Melissa, Hanjie
 * @version 1.0 11/11/13
 */
public class LandOffice {	 
	private Random randomGen; 
	
	public LandOffice() {
		this.randomGen = new Random(); 
	}
	
	/**
	 * This method sells the tile after the first 2 rounds
	 * 
	 * MAKE SURE TO ONLY USE THIS METHOD AFTER HASMONEY ONLY... 
	 * need to have a random price generated
	 * 
	 * Sets the owner of the tile 
	 * Adds tile to list of Tiles for the player
	 * Removes from the available tiles array list
	 * Removes any mules that may be on that tile 
	 * Updates the player's money
	 */
	public boolean sellTile(Player player, Tile tile) {
		if (!isTileAvailable(tile)) {
			return false;
		} else if (isFreeProperty()) {
			if (player.getFirstTimeFreeLand()) {
				changeOwnerOperations(player, tile);
				player.setFirstTimeFreeLand(false);
				return true;
			} else {
				return false;
			}
		} else {
			int sellingPrice = getSellingPrice();
			if (hasMoney(player, getSellingPrice())) {
				player.subtractMoney(sellingPrice);
				changeOwnerOperations(player, tile);
				return true;
			} else {
				return false;
			}
		}
	}
	
	/**
	 * Sets a tile to an(other) owner and remove the mule
	 * 
	 * @param Player player
	 * @param Tile tile
	 * @return
	 */
	private void changeOwnerOperations(Player player, Tile tile) {
		player.addOwnedTile(tile);
	}
	
	/**
	 * This method checks to see if the player can afford a tile.
	 * Only use this method after the 2nd round.
	 * It creates a random price for the tile to be sold at
	 * 
	 * @param Player player
	 * @param int price
	 * @return true if has enough money
	 */
	private boolean hasMoney(Player player, int price) {
		int playerMoney = player.getMoney();
		//checks to see if the player has enough money 
		return (playerMoney >= price);
	}

	/**
	 * Checks game is in free property round
	 * 
	 * @return true if first 2 rounds
	 */
	public boolean isFreeProperty(){
		int round = Game.getInstance().getCurrentRound(); 
		return (round <= 2); 
	}
	
	/**
	 * This method buys a tile from a player 
	 * Remove owner of the tile (sets to null)
	 * Adds to available tiles array list
	 * Removes tile from player's list of owned tiles 
	 * Updates the player's money
	 * 
	 * @param Player player
	 * @param Tile tile
	 */
	public void buyTile(Player player, Tile tile) {
		player.removeTile(tile);
		player.addMoney(getBuyingPrice());
	}
	
	/**
	 * Generates and returns the random price at which
	 * the land office will SELL the tile 
	 * 
	 * @return random price
	 */
	private int getSellingPrice() {
		int randNum = randomGen.nextInt(101);
		int randomPrice = 300 + Game.getInstance().getCurrentRound() * randNum;
		return randomPrice;
	}
	
	/**
	 * Generates and returns the random price at which
	 * the land office will BUY a tile
	 * 
	 * @return random price
	 */
	private int getBuyingPrice() {
		int randomPrice = 400 + randomGen.nextInt(201); 
		return randomPrice; 
	}
	
	/**
	 * Checks whether a tile is town or owned by a player
	 * 
	 * @return if tile is available for sale
	 */
	private boolean isTileAvailable(Tile tile) {
		if (tile.getTerrain() == Tile.TERRAIN_TOWN) {
			return false;
		} else {
			List<Player> players = Game.getInstance().getPlayers();
			for (Player p : players) {
				if (p.isOwnedTile(tile)) {
					return false;
				}
			}
		}
		return true;
	}
}
